 #include<iostream>
#include<string>
#include<cstring>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>

 static void usage(std::string proc)
 {
    std::cout<<"\nUsage: "<< proc<<" SeverIp  ServerPort\n"<<std::endl;
 }
 int main(int argc,char* argv[])
 {
   if(argc!=3)
   {
      usage(argv[0]);
      exit(1);
   }
   int sock=socket(AF_INET,SOCK_DGRAM,0);
   if(sock<0)
   {
      std::cerr<<"socket error"<<std::endl;
      exit(2);
   }
   //client也需要bind，但是不会显式绑定，程序员不会手动绑定
   //client是面向用户的，如果程序员自己bind了，那么客户端就会固定了一个固定的ip和端口，如果其他客户端
   //已经占用了这个固定的端口就会出事，所以client不会自己写bind指定port,要让操作系统自己随机bind
   
   std::string message;
   char buffer[1024];
   //客户端设置目标服务器设置
   struct sockaddr_in server;
   memset(&server,0,sizeof(server));
   server.sin_family=AF_INET;
   server.sin_port=htons(atoi(argv[2])); 
   server.sin_addr.s_addr=inet_addr(argv[1]);
   socklen_t len=sizeof(server);
   while(true)
   {
      //从键盘输出要发送的信息
      std::cout<<"please input your information->"<<std::endl;
      std::getline(std::cin,message);
      if(message=="quit") break;
      //当client 首次发送消息给服务器时候，OS会自动给client bind它的IP和port
      sendto(sock,message.c_str(),message.size(),0,(struct sockaddr*)&server,len);
      struct sockaddr_in temp;
      socklen_t tempLen=sizeof(temp);
      ssize_t s=recvfrom(sock,buffer,sizeof(buffer),0,(struct sockaddr*)&temp,&tempLen);
      if(s>0)
      {
         buffer[s]=0;
         std::cout<<"server echo# "<<buffer<<std::endl;
      }
   }
   close(sock);
   return 0;
 }